﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace nl.hanze.i.web.t41
{
    class Mens
    {
        private String naam;
        private DateTime geboortedatum;
        private long bsn;
        private Sexe geslacht;

        public Mens() 
        {}

        public Mens(String naam, DateTime geboortedatum, long bsn, Sexe geslacht)
        {
            this.naam = naam;
            this.geboortedatum = geboortedatum;
            this.bsn = bsn;
            this.geslacht = geslacht;
        }

        // Getter and setter for naam
        public String Naam
        {
            get { return naam; }
            set { naam = value; }
        }

        // Getter and setter for geboortedatum
        public DateTime Geboortedatum
        {
            get { return geboortedatum; }
            set { geboortedatum = value; }
        }

        // Getter and setter for bsn
        public String Bsn
        {
            get 
            {
                String newBSN = bsn + "";
                while (newBSN.Length < 15) {newBSN = "0" + newBSN; }
                return newBSN; 
            }
            set 
            { 
                bsn = long.Parse(value); 
            }
        }

        // Getter and setter for geslacht
        public Sexe Geslacht
        {
            get { return geslacht; }
            set { geslacht = value; }
        }

        // Calculate's current age
        public int getAge()
        {
            int years = DateTime.Now.Year - this.geboortedatum.Year;
            if (DateTime.Now.Month < this.geboortedatum.Month || (DateTime.Now.Month == this.geboortedatum.Month && DateTime.Now.Day < this.geboortedatum.Day)) 
                years--;
            
            return years;
        }

        // Operator overload +
        public static Mens operator +(Mens a, Mens b)
        {
            try
            {
                if (a.geslacht != b.geslacht && a.above16() && b.above16())
                {
                    int seed = (a.getAge() + b.getAge()) * (System.Convert.ToInt32(a.Bsn) + System.Convert.ToInt32(b.Bsn));
                    String name = makeName(6, seed);

                    // Make the actual baby
                    Mens baby = new Mens(makeName(6, seed), generateGeboortedatum(-14, 14, seed), Program.laatstebsn++, randomSexe(seed));

                    return baby;
                }
            }
            catch(GeenZwangerschapMogelijkException e)
            {
                e.print();
                throw e;
            }
            return null;
        }

        // Random naam maken voor een mens
        private static String makeName(int size, int randomSeed)
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random(randomSeed);
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            return builder.ToString();
        }

        // Calculate if Mens is older than 16
        private Boolean above16()
        {
            if (this.getAge() < 16)
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        // Generate birthday for new Mens
        private static DateTime generateGeboortedatum(int start, int end, int randomSeed)
        {
            Random random = new Random(randomSeed);
            int daysInMonth = 365 / 12;
            int daysToAdd = (daysInMonth * 9) + random.Next(start, end);
            DateTime today = DateTime.Now;
            TimeSpan interval = new TimeSpan(daysToAdd, 0, 0, 0);
            return today.Subtract(interval);
        }

        // Randomly pick a Sexe
        private static Sexe randomSexe(int seed)
        {
            Random random = new Random(seed);
            Sexe geslacht = ((Sexe)(random.Next(1, 3)));
            return geslacht;
        }
    }
}